const { app } = require("electron")
const path = require("path")
const fs = require("fs-extra")
const Database = require("better-sqlite3-multiple-ciphers")
const PROJECT_NAME = "demoDesktop"
const USER_DATA_DIR = app.getPath("userData")
const PROJECT_ROOT_DIR = path.join(USER_DATA_DIR, PROJECT_NAME)
const DB_DIR = path.join(PROJECT_ROOT_DIR, "db")
console.log('DB_DIR is :', DB_DIR)
class BetterSqlite3 {
  constructor(options = {}) {
    fs.mkdirpSync(DB_DIR)
    this.sqlcriper = options.sqlcriper || false
    this.key = options.key || "abcd"
    this.db = new Database(path.join(DB_DIR, "demoDesktop.db"), {
      timeout: options.timeout || 5 * 1000,
      fileMustExist: options.fileMustExist || false,
      verbose: (...args) => {
        console.log(args)
      },
    })
  }
  resetKey(rekey) {
    this.setCriper()
    this.db.pragma(`rekey='${rekey}'`)
  }
  setCriper() {
    this.sqlcriper && this.db.pragma(`key='${this.key}'`)
  }
  tableIsExist(tableName) {
    this.setCriper()
    try {
      this.db.prepare(`SELECT 1 FROM ${tableName} LIMIT 1`).run()
      return true
    } catch (err) {
      return false
    }
  }
  createTable(tableName, columns = []) {
    this.setCriper()
    const isExist = this.tableIsExist(tableName)
    if (!isExist) {
      this.db.prepare(`CREATE TABLE ${tableName}(${columns.join(",")})`).run()
    }
  }
  checkTableAndColumns(tableName, columns) {
    this.setCriper()
    this.createTable(tableName, columns)
    this.updateTableColumn(tableName, columns)
  }
  // ========== 列操作 ==========
  addTableColumn(tableName, column) {
    this.setCriper()
    return this.db.prepare(`ALTER TABLE ${tableName} add ${column}`).run()
  }
  renameTableColumn(tableName, oldColumn, newColumn) {
    this.setCriper()
    return this.db.prepare(`ALTER TABLE ${tableName} alter ${oldColumn} ${newColumn}`).run()
  }
  deleteTableColumn(tableName, column) {
    this.setCriper()
    return this.db.prepare(`ALTER TABLE ${tableName} drop column ${column}`).run()
  }
  updateTableColumn(tableName, currentColumns) {
    this.setCriper()
    const oldColumnMap = this.db.prepare(`SELECT * FROM ${tableName} LIMIT 1`).get()
    if (oldColumnMap) {
      const oldColumns = Object.keys(oldColumnMap)
      currentColumns.forEach((columnName) => {
        if (!oldColumns.includes(columnName)) {
          this.addTableColumn(tableName, columnName)
        }
      })
    }
  }
  // ========== 增删改查 ==========
  insert(sql, ...args) {
    this.setCriper()
    return this.db.prepare(sql).run(args)
  }
  update(sql, ...args) {
    this.setCriper()
    return this.db.prepare(sql).run(args)
  }
  delete(sql, ...args) {
    this.setCriper()
    return this.db.prepare(sql).run(args)
  }
  getOne(sql, ...args) {
    this.setCriper()
    return this.db.prepare(sql).get(args)
  }
  getAll(sql, ...args) {
    this.setCriper()
    return this.db.prepare(sql).all(args)
  }
  getCount(sql, ...args) {
    this.setCriper()
    return this.db.prepare(sql).get(args).count
  }
}

module.exports = BetterSqlite3
